#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
// GLM 库用于数学运算
#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE // Vulkan 深度范围
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <chrono> // 用于时间计算
#include <iostream>
#include <stdexcept>
#include <cstdlib>
#include <vector>

#include <array>
#include <set>
#include <optional> // C++17
#include <algorithm>
#include <map>

#include <fstream>

const int WIDTH = 800;
const int HEIGHT = 600;
// const int MAX_FRAMES_IN_FLIGHT = 2;
// --- 结构 1: 顶点数据 ---
struct Vertex
{
    glm::vec3 pos;
    glm::vec3 color; // 只需要位置坐标

    // 告诉 Vulkan 如何解释顶点数据
    static VkVertexInputBindingDescription getBindingDescription()
    {
        VkVertexInputBindingDescription bindingDescription{};
        bindingDescription.binding = 0;
        bindingDescription.stride = sizeof(Vertex);
        bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
        return bindingDescription;
    }

    // 告诉 Vulkan 顶点属性的布局（位置）
    static std::array<VkVertexInputAttributeDescription, 2> getAttributeDescriptions()
    {
        std::array<VkVertexInputAttributeDescription, 2> attributeDescriptions{};

        // 属性 0: 位置 (pos)
        attributeDescriptions[0].binding = 0;
        attributeDescriptions[0].location = 0;
        attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT; // 2个浮点数
        attributeDescriptions[0].offset = offsetof(Vertex, pos);

        // 属性 1: 颜色 (color) - location 1
        attributeDescriptions[1].binding = 0;
        attributeDescriptions[1].location = 1;
        attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
        attributeDescriptions[1].offset = offsetof(Vertex, color);

        return attributeDescriptions;
    }
};

// LumineVulkan.cpp

const std::vector<Vertex> vertices = {
    // ----------------------------------------------------
    // 底部正方形 (两个三角形) - 颜色: 蓝色
    // ----------------------------------------------------
    // 三角形 1
    {{-0.5f, -0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}}, // 0: 左下后
    {{0.5f, -0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}},  // 1: 右下后
    {{0.5f, -0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}},   // 2: 右下前

    // 三角形 2
    {{-0.5f, -0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}}, // 0: 左下后
    {{0.5f, -0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}},   // 2: 右下前
    {{-0.5f, -0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}},  // 3: 左下前

    // ----------------------------------------------------
    // 四个侧面三角形 (顶点 V_top = (0, 0.5, 0))
    // ----------------------------------------------------

    // 侧面 1 (后侧) - 颜色: 红色
    {{0.0f, 0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}},    // V_top
    {{0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}},  // V_1 (右下后)
    {{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, // V_0 (左下后)

    // 侧面 2 (右侧) - 颜色: 绿色
    {{0.0f, 0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}},   // V_top
    {{0.5f, -0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}},  // V_2 (右下前)
    {{0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}}, // V_1 (右下后)

    // 侧面 3 (前侧) - 颜色: 黄色
    {{0.0f, 0.5f, 0.0f}, {1.0f, 1.0f, 0.0f}},   // V_top
    {{-0.5f, -0.5f, 0.5f}, {1.0f, 1.0f, 0.0f}}, // V_3 (左下前)
    {{0.5f, -0.5f, 0.5f}, {1.0f, 1.0f, 0.0f}},  // V_2 (右下前)

    // 侧面 4 (左侧) - 颜色: 紫色
    {{0.0f, 0.5f, 0.0f}, {1.0f, 0.0f, 1.0f}},    // V_top
    {{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 1.0f}}, // V_0 (左下后)
    {{-0.5f, -0.5f, 0.5f}, {1.0f, 0.0f, 1.0f}}   // V_3 (左下前)
};

// --- 结构 2: Uniform 缓冲对象 (UBO) ---
// 用于将时间数据传递给着色器
struct UniformBufferObject
{
    glm::mat4 model;
    glm::mat4 view;
    glm::mat4 proj;
    float time;
    glm::vec3 padding; // 填充，确保数据对齐
};

const std::vector<const char *> validationLayers = {
    "VK_LAYER_KHRONOS_validation"};

// 应用程序必需的设备扩展列表
const std::vector<const char *> deviceExtensions = {
    VK_KHR_SWAPCHAIN_EXTENSION_NAME};

// ----------------------------------------------------
// 辅助结构：用于存储队列家族索引
// ----------------------------------------------------

struct SwapChainSupportDetails
{
    VkSurfaceCapabilitiesKHR capabilities;
    std::vector<VkSurfaceFormatKHR> formats;
    std::vector<VkPresentModeKHR> presentModes;
};
#ifdef NDEBUG
const bool enableValidationLayers = false;
#else
const bool enableValidationLayers = true;
#endif